
#include "config.h"#include <stdio.h>
#include <time.h>
#include <inttypes.h>#include <amanita/aMath.h>
#include <amanita/aVector.h>
#include <amanita/sqlite/aSQLite.h>
#include <amanita/net/aHttp.h>
#include "Main.h"
#include "TextPage.h"
#include "EditPage.h"
#include "astro/Astrology.h"


symbol_t TextPage::history[1024] = { 0 };
int TextPage::history_len = 0;
int TextPage::history_index = -1;


void TextPage::webview_hover_event_callback(WebKitWebView *webview,gchar *title,gchar *uri,gpointer data) {
	app.handleAction(ACTION_SHOW_STATUS,0,(void *)(uri? uri : aString::blank));
}

gboolean TextPage::webview_navigation_decision_event_callback(WebKitWebView *webview,WebKitWebFrame *frame,WebKitNetworkRequest *request,
																	WebKitWebNavigationAction *action,WebKitWebPolicyDecision *decision,gpointer data) {
	int reason = webkit_web_navigation_action_get_reason(action);
	if(reason>=WEBKIT_WEB_NAVIGATION_REASON_LINK_CLICKED && reason<=WEBKIT_WEB_NAVIGATION_REASON_FORM_RESUBMITTED) {
		TextPage &page = *(TextPage *)data;
//		const gchar *uri = webkit_web_navigation_action_get_original_uri(action);
		const gchar *uri = webkit_network_request_get_uri(request);
app.printf("TextPage::webview_navigation_decision_event_callback(uri=\"%s\",reason=%d)",uri,reason);
		webkit_web_policy_decision_ignore(decision);
		app.handleAction(ACTION_SHOW_STATUS,0,(void *)aString::blank);
		page.navigate(uri);
		return TRUE;
	} else return FALSE;
}

/*gboolean TextPage::webview_navigation_event_callback(WebKitWebView *webview,WebKitWebFrame *frame,WebKitNetworkRequest *request,gpointer data) {
//	TextPage &page = *(TextPage *)data;
//	const gchar *uri = webkit_web_navigation_action_get_original_uri(action);
	const gchar *uri = webkit_network_request_get_uri(request);
app.printf("TextPage::webview_navigation_event_callback(uri=\"%s\")",uri);
	app.handleAction(ACTION_SHOW_STATUS,0,(void *)aString::blank);
//	page.navigate(uri);
	return TRUE;
}*/

void TextPage::go_back_callback(GtkWidget* widget, gpointer data) {
	TextPage &page = *(TextPage *)data;
	page.goBack();
}

void TextPage::go_forward_callback(GtkWidget* widget,gpointer data) {
	TextPage &page = *(TextPage *)data;
	page.goForward();
}

void TextPage::find_callback(GtkWidget* widget, gpointer data) {
//	TextPage &page = *(TextPage *)data;
}

void TextPage::help_callback(GtkWidget* widget, gpointer data) {
//	TextPage &page = *(TextPage *)data;
}


TextPage::TextPage() : Page(),status(0),id(0),symbol(0) {
app.printf("TextPage()");
	init();
}

TextPage::TextPage(symbol_t s) : Page(),status(0),id(0),symbol(s) {
app.printf("TextPage(symbol_t=%" PRIu64 ")",s);
	init();
	setDocument(s);
}

TextPage::TextPage(const char *uri) : Page(),status(0),id(0),symbol(0) {
app.printf("TextPage(url=%s)",uri);
	init();
	navigate(uri);
}

TextPage::~TextPage() {
app.printf("TextPage::~TextPage()");
}


void TextPage::init() {
app.printf("TextPage::init()");

	GtkWidget *page = gtk_vbox_new(FALSE,0);

	GtkWidget* toolbar = gtk_toolbar_new();
	gtk_orientable_set_orientation(GTK_ORIENTABLE(toolbar),GTK_ORIENTATION_HORIZONTAL);
	gtk_toolbar_set_style(GTK_TOOLBAR(toolbar),GTK_TOOLBAR_BOTH_HORIZ);
	{
		GtkToolItem *item;
		item = gtk_tool_button_new_from_stock(GTK_STOCK_GO_BACK);
		g_signal_connect(G_OBJECT(item),"clicked",G_CALLBACK(go_back_callback),this);
		gtk_toolbar_insert(GTK_TOOLBAR(toolbar),item,-1);

		item = gtk_tool_button_new_from_stock(GTK_STOCK_GO_FORWARD);
		g_signal_connect(G_OBJECT(item),"clicked",G_CALLBACK(go_forward_callback),this);
		gtk_toolbar_insert(GTK_TOOLBAR(toolbar),item,-1);

		item = gtk_tool_button_new_from_stock(GTK_STOCK_FIND);
		g_signal_connect(G_OBJECT(item),"clicked",G_CALLBACK(find_callback),this);
		gtk_toolbar_insert(GTK_TOOLBAR(toolbar),item,-1);

		item = gtk_tool_button_new_from_stock(GTK_STOCK_HELP);
		g_signal_connect(G_OBJECT(item),"clicked",G_CALLBACK(help_callback),this);
		gtk_toolbar_insert(GTK_TOOLBAR(toolbar),item,-1);
	}
	gtk_box_pack_start(GTK_BOX(page),toolbar,FALSE,FALSE,0);

	GtkWidget *scroll = gtk_scrolled_window_new(NULL,NULL);
//	gtk_widget_set_size_request(scroll,330,-1);
	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll),GTK_POLICY_AUTOMATIC,GTK_POLICY_ALWAYS);
//	gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scroll),GTK_SHADOW_IN);
	{
		gtk.webview = webkit_web_view_new();
		WebKitWebSettings *settings = webkit_web_settings_new ();
		g_object_set(settings,
			"auto-load-images",TRUE,
			"auto-shrink-images",FALSE,
			"default-encoding","UTF-8",
			"enable-plugins",FALSE,
			NULL);
		webkit_web_view_set_settings(WEBKIT_WEB_VIEW(gtk.webview),settings);
		g_signal_connect(G_OBJECT(gtk.webview),"hovering-over-link",G_CALLBACK(webview_hover_event_callback),this);
		g_signal_connect(G_OBJECT(gtk.webview),"navigation-policy-decision-requested",G_CALLBACK(webview_navigation_decision_event_callback),this);
//		g_signal_connect(G_OBJECT(gtk.webview),"navigation-requested",G_CALLBACK(webview_navigation_event_callback),this);
		gtk_container_add(GTK_CONTAINER(scroll),gtk.webview);
	}
	gtk_box_pack_end(GTK_BOX(page),scroll,TRUE,TRUE,0);

	Page::open(aString::blank,page);
}

void TextPage::clearHistory() {
	history_len = 0;
	history_index = -1;
}

void TextPage::loadHistory() {
	clearHistory();
	size_t n;
	char str[256];
	sprintf(str,"%shistory.dat",app.getHomeDir());
	FILE *fp = fopen(str,"rb");
	if(!fp) return;
	n = fread(&history_len,sizeof(int),1,fp);
	n = fread(&history_index,sizeof(int),1,fp);
	n = fread(history,1024*sizeof(symbol_t),1,fp);
	(void)n;
	fclose(fp);
}

void TextPage::saveHistory() {
	size_t n;
	char str[256];
	sprintf(str,"%shistory.dat",app.getHomeDir());
	FILE *fp = fopen(str,"wb");
	n = fwrite(&history_len,sizeof(int),1,fp);
	n = fwrite(&history_index,sizeof(int),1,fp);
	n = fwrite(history,1024*sizeof(symbol_t),1,fp);
	(void)n;
	fclose(fp);
}

void TextPage::goBack() {
	if(history_index<=0) return;
	setDocument(history[--history_index]);
}

void TextPage::goForward() {
	if(history_len==0 || history_index==history_len-1) return;
	setDocument(history[++history_index]);
}

void TextPage::addToHistory(symbol_t s) {
	if(history_index>=0 && history[history_index]==s) return;
	if(history_len==1024 && history_index==1023) {
		memmove(history,&history[512],512*sizeof(symbol_t));
		history_len = 512;
		history_index = 511;
	}
	history[++history_index] = s;
	history_len = history_index+1;
}

void TextPage::navigate(const char *uri) {
app.printf("TextPage::navigate(uri=%s)",uri);
	if(!uri || !*uri) return;
	if(!strncmp(uri,"symbol://",9)) {
		char p[strlen(uri)-8];
		strcpy(p,&uri[9]);
		char *p1 = strchr(p,'#'),*p2 = strchr(p1? p1+1 : p,'?');
		if(p1) *p1++ = '\0';
		if(p2) *p2++ = '\0';

		uint64_t i = (uint64_t)(p1? atoll(p1) : 0);
		symbol_t s = (symbol_t)atoll(p);
		if(p2) {
			if((s || i) && !strncmp(p2,"edit",4)) {
				new EditPage(s,i);
				return;
			} else if(i && !strncmp(p2,"delete",6)) {
				aHttp http(app);
				http.getf(WEB_HOST,WEB_PATH "text.php?cmd=delete&k=%s&id=%" PRIu64,app.local_key,i);
			}
		}
		if(s) setDocument(s);
	}
}

void TextPage::setDocument(symbol_t s) {
app.printf("TextPage::setDocument(symbol=%" PRIu64 ")",s);
	aString title("",256),html("",1024);
	Symbol sym;
	symbol_t n[21] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };

	symbol = s;
	id = 0;

	app.occult.parseCode(symbol,sym);
	n[0] = symbol;
	writeTitle(title,sym,n);
	setTabLabelText(title.toCharArray());

	addToHistory(symbol);

app.printf("TextPage::setDocument(symbol=%" PRIu64 ",system=%d,n=%d,concept=%d,c1=%d,c2=%d,c3=%d,c4=%d)",sym.symbol,sym.system,sym.n,sym.concept,sym.c1,sym.c2,sym.c3,sym.c4);

	writeHead(html,title);
	writeArticle(html,title,sym);
	writeReferences(html,sym,&n[1]);
//	html.append("<p>").append(url).append("</p>\r\n");
	writeFoot(html);
fprintf(stderr,"HTML('%s') {\n\n%s\n\n}\n",title.toCharArray(),html.toCharArray());
fflush(stderr);

	webkit_web_view_load_string(WEBKIT_WEB_VIEW(gtk.webview),html.toCharArray(),"text/html","UTF-8","file://./");
}

void TextPage::writeTitle(aString &title,Symbol &s,symbol_t *refs) {
	switch((int)s.system) {
		case OCCULT_ASTROLOGY:Astrology::getCodeHeader(title,s,&refs[1]);break;
		case OCCULT_QABALAH:
		case OCCULT_TAROT:
		case OCCULT_ENOCH:
		case OCCULT_ALCHEMY:title.append(app.occult.system(s.system));break;
	}
}

void TextPage::writeHead(aString &html,aString &title) {
	html.append("<html>\n"
		"<head>\n"
//		"<style>").include(HTML_PATH "style.css").include(HTML_PATH "style.text.css").append("</style>\n"
//		"<script>").include(HTML_PATH "script.js").append("</script>\n</head>\n\n<body class=\"text\">\n");
		"<link type=\"text/css\" rel=\"stylesheet\" href=\"").append(app.getHomeDir()).append("style.css\" />\n"
		"<link type=\"text/css\" rel=\"stylesheet\" href=\"").append(app.getHomeDir()).append("style.text.css\" />\n"
		"<script src=\"").append(app.getHomeDir()).append("script.js\"></script>\n"
		"</head>\n\n"
		"<body class=\"text\">\n");
	html.append("<h1>").append(title).append("</h1>\n");
}

bool TextPage::writeArticle(aString &html,aString &title,Symbol &s) {
app.printf("TextPage::writeArticle(1)");
	aHttp http(app);
	const char *txt = http.getf(WEB_HOST,WEB_PATH "text.php?k=%s&symbol=%" PRIu64 "&format=html",app.local_key,s.symbol);
app.printf("TextPage::writeArticle(txt=%s)",txt);
	/*if(r) html.append("<p>").append(r->getString(2)).append("</p>\n").append("<p>[<a href=\"ref://").
		append(s.symbol).append(':').append((uint64_t)r->getLongLong(0)).append("/edit\">").append("Redigera").
		append("</a>][<a href=\"ref://").append(s.symbol).append(':').append((uint64_t)r->getLongLong(0)).
		append("/delete\">").append("Ta bort").append("</a>]</p>\n");*/
	if(txt && *txt) html.append(txt);
	else html.append("<p><b>").append("Saknas text för").append(" \"").append(title).append("\" ").
		append("i databasen!").append("</b></p>\n");
	return true;
}

void TextPage::writeReferences(aString &html,Symbol &s,symbol_t *n) {
	int i,j;
	html.append("<div class=\"text_controls\">\n"
			"\t<div class=\"button\"><a href=\"symbol://").append(s.symbol).append("?edit\">").append("Skriv ny text").append("</a></div>\n"
			"\t<div class=\"clear\"></div>\n"
		"</div>");
	for(i=0,j=0; i<20; i++) if(n[i]) {
		if(j++==0) html.append("<div class=\"text box\">\n"
			"\t<h5>").append("Angränsande ämnen").append(":</h5><br>\n");
		html.append("\t<div class=\"text_ref\"><a href=\"symbol://").append(n[i]).append("\">");
		Astrology::getCodeHeader(html,n[i]);
		html.append("</a><div>\n");
	}
	if(j>0) html.append("</div>\n");
}

void TextPage::writeFoot(aString &html) {
	html.append("</body>\n"
		"</html>\n");
}



